package cn.jbolt.ai.resource.embedding;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.jboltai.resource.embedding.EmbeddingModel;
import com.tencent.tcvectordb.model.param.collection.Embedding;

import java.util.*;
import java.util.stream.Collectors;


public enum EmbeddingModelType {

    SILICONFLOW("siliconflow", "硅基流动", new ConfigItem[]{
            ConfigItem.ofDefaultModel(true, null),
            ConfigItem.ofApiKey(true, null),
            ConfigItem.ofDimension(true, null),
            ConfigItem.ofApiUrl(false, null),
    }),
    OLLAMA("ollama", "Ollama", new ConfigItem[]{
            ConfigItem.ofDefaultModel(true, null),
            ConfigItem.ofApiUrl(true, "apiUrl一般为http://{Ollama所在服务器ip}:11434/api/embeddings"),
            ConfigItem.ofDimension(true, null)
    }),
    TONGYI_V3("text-embedding-v3", "通义V3", new ConfigItem[]{
            ConfigItem.ofApiKey(true, null),
            ConfigItem.ofApiUrl(false, null),
            ConfigItem.ofDimension(false, null).setDefaultValue(EmbeddingModel.TONGYI_V3.getDimension()+"").setReadonly(true)
    }),
    BAICHUAN("Baichuan-Text-Embedding", "百川", new ConfigItem[]{
            ConfigItem.ofApiKey(true, null),
            ConfigItem.ofApiUrl(false, null),
            ConfigItem.ofDimension(false, null).setDefaultValue(EmbeddingModel.BAI_CHUAN.getDimension()+"").setReadonly(true)
    }),

    TONGYI_V2("text-embedding-v2", "通义V2", new ConfigItem[]{
            ConfigItem.ofApiKey(true, null),
            ConfigItem.ofApiUrl(false, null),
            ConfigItem.ofDimension(false, null).setDefaultValue(EmbeddingModel.TONGYI_V2.getDimension()+"").setReadonly(true)
    }),


    OPENAI_ADA002("text-embedding-ada-002", "OpenAI-ADA002", new ConfigItem[]{
            ConfigItem.ofApiKey(true, null),
            ConfigItem.ofApiUrl(false, "OpenAI推荐使用海外代理服务进行请求"),
            ConfigItem.ofDimension(false, null).setDefaultValue(EmbeddingModel.OPENAI_ADA002.getDimension()+"").setReadonly(true)
    }),

    OPENAI_3_SMALL("text-embedding-3-small", "OpenAI-3-SMALL", new ConfigItem[]{
            ConfigItem.ofApiKey(true, null),
            ConfigItem.ofApiUrl(false, "OpenAI推荐使用海外代理服务进行请求"),
            ConfigItem.ofDimension(false, null).setDefaultValue(EmbeddingModel.OPENAI_3_SMALL.getDimension()+"").setReadonly(true)
    }),






    TENCENT_BGE_BASE_ZH(EmbeddingModel.TENCENT_BGE_BASE_ZH.getDefaultModel(), EmbeddingModel.TENCENT_BGE_BASE_ZH.getName(), null),
    TENCENT_M3E_BASE(EmbeddingModel.TENCENT_M3E_BASE.getDefaultModel(), EmbeddingModel.TENCENT_M3E_BASE.getName(), null),
    TENCENT_E5_LARGE_V2(EmbeddingModel.TENCENT_E5_LARGE_V2.getDefaultModel(), EmbeddingModel.TENCENT_E5_LARGE_V2.getName(), null),
    TENCENT_TEXT2VEC_LARGE_CHINESE(EmbeddingModel.TENCENT_TEXT2VEC_LARGE_CHINESE.getDefaultModel(), EmbeddingModel.TENCENT_TEXT2VEC_LARGE_CHINESE.getName(), null),
    TENCENT_MULTILINGUAL_E5_BASE(EmbeddingModel.TENCENT_MULTILINGUAL_E5_BASE.getDefaultModel(), EmbeddingModel.TENCENT_MULTILINGUAL_E5_BASE.getName(), null),


    ;

    private String name;

    private String sn;

    private ConfigItem[] configItems;

    EmbeddingModelType(String sn, String name, ConfigItem[] configItems) {
        this.sn = sn;
        this.name = name;
        this.configItems = configItems;
    }


    public String getName() {
        return name;
    }

    public String getSn() {
        return sn;
    }

    public ConfigItem[] getConfigItems() {
        return configItems;
    }


    /**
     * 根据sn查找对应的模型类型
     * @param sn
     * @return
     */
    public static EmbeddingModelType getBySn(String sn) {
        if (sn == null) {
            throw new IllegalArgumentException("Embedding model sn 不能为 null");
        }
        return Arrays.stream(values())
                .filter(type -> type.getSn().equals(sn))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("未找到匹配的 Embedding model : " + sn));
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    private static class ConfigItem {

        /**
         * 默认大模型的配置项
         *
         * @param required
         * @param remark
         * @return
         */
        static ConfigItem ofDefaultModel(boolean required, String remark) {
            return new ConfigItem("defaultModel", required, remark);
        }


        static ConfigItem ofDimension(boolean required, String remark) {
            return new ConfigItem("dimension", required, remark);
        }

        /**
         * api_key配置项
         *
         * @param required
         * @param remark
         * @return
         */
        static ConfigItem ofApiKey(boolean required, String remark) {
            return new ConfigItem("apiKey", required, remark);
        }

        /**
         * api_key配置项
         *
         * @param required
         * @param remark
         * @return
         */
        static ConfigItem ofSecretKey(boolean required, String remark) {
            return new ConfigItem("secretKey", required, remark);
        }

        /**
         * api_url配置项
         *
         * @param required
         * @param remark
         * @return
         */
        static ConfigItem ofApiUrl(boolean required, String remark) {
            return new ConfigItem("apiUrl", required, remark);
        }


        /**
         * 配置字段
         */
        private String field;

        private String defaultValue;

        private boolean readonly;

        /**
         * 是否必填
         */
        private boolean required;

        /**
         * 备注
         */
        private String remark;

        public ConfigItem(String field, boolean required, String remark) {
            this.field = field;
            this.required = required;
            this.remark = remark;
        }

        public String getField() {
            return field;
        }

        public boolean isRequired() {
            return required;
        }

        public String getRemark() {
            return remark;
        }

        public String getDefaultValue() {
            return defaultValue;
        }

        public ConfigItem setDefaultValue(String defaultValue) {
            this.defaultValue = defaultValue;
            return this;
        }

        public boolean isReadonly() {
            return readonly;
        }

        public ConfigItem setReadonly(boolean readonly) {
            this.readonly = readonly;
            return this;
        }
    }


    /**
     * 将枚举转换为所需的列表格式，忽略Tencent内置
     * @return
     */
    public static List<Map<String, Object>> list() {
        return Arrays.asList(values()).stream().filter(item -> item.getSn().startsWith("Tencent") == false)
                .map(modelType -> {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("sn", modelType.sn);
            map.put("name", modelType.name);
            map.put("configItems", modelType.getConfigItems());
            return map;
        }).collect(Collectors.toList());
    }
    /**
     * 将枚举转换为所需的列表格式，包含Tencent内置
     * @return
     */
    public static List<Map<String, Object>> listWithTencent() {
        return Arrays.asList(values()).stream()
                .map(modelType -> {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("sn", modelType.sn);
            map.put("name", modelType.name);
            map.put("configItems", modelType.getConfigItems());
            return map;
        }).collect(Collectors.toList());
    }






}
